# -*- coding: utf-8 -*-
"""
@version: 0.1
@author: ljt
@license: IdooSmart
@contact: 1329331182@qq.com 
@software: PyCharm
@file: base_request_handler.py
@time: 2019/8/29 11:27
@descript:
"""
import json
import uuid
import abc

from tornado.web import RequestHandler
from tornado import gen
from tornado.web import HTTPError
from concurrent.futures import ThreadPoolExecutor
from tornado.concurrent import run_on_executor

from ScoreCard.log.logger_config import logger


class BaseRequestHandler(RequestHandler):
    executor = ThreadPoolExecutor(8)

    # blog.csdn.net/moshowgame 解决跨域问题
    def set_default_headers(self):
        self.set_header('Access-Control-Allow-Origin', '*')
        self.set_header('Access-Control-Allow-Headers', 'json')
        self.set_header('Access-Control-Max-Age', 1000)
        self.set_header('Content-type', 'application/json')
        self.set_header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')
        self.set_header('Access-Control-Allow-Headers',  'authorization, Authorization, Content-Type, Access-Control-Allow-Origin, Access-Control-Allow-Headers, X-Requested-By, Access-Control-Allow-Methods')

    # 定义下面的函数

    @gen.coroutine
    def get(self, *args, **kwargs):
        self.set_default_headers()
        request_id = uuid.uuid1().hex
        api_url = self.reverse_url(self.__class__.__name__)
        callbackfun = self.get_argument("callback", "")  # 接受callback的名字callbackfun=jsonpCallback
        try:
            result, cache_id, request = yield self._get(request_id, api_url, *args, **kwargs)
            result["requestId"] = request_id
            result["code"] = 200
            result["message"] = 'success'
            result = json.dumps(result)
            is_jsonp = request.get('is_jsonp',True)
            if is_jsonp:
                self.write(result)
            else:
                self.write('' + callbackfun + '(' + result + ')')
        except HTTPError as e:
            status_code = '[%s]: %s' % (e.status_code, str(e))
            result = {"requestId": request_id,
                      "code": status_code,
                      "message": str(e)}
            result = json.dumps(result)
            request = self._get_request_arguments(*args, **kwargs)
            is_jsonp = request.get('is_jsonp', False)
            if is_jsonp:
                self.write(result)
            else:
                self.write('' + callbackfun + '(' + result + ')')
        except Exception as e:
            status_code = '[%s]: %s' % (500, str(e))
            result = {"requestId": request_id,
                      "code": status_code,
                      "message": str(e)}
            result = json.dumps(result)
            request = self._get_request_arguments(*args, **kwargs)
            is_jsonp = request.get('is_jsonp', False)
            if is_jsonp:
                self.write(result)
            else:
                self.write('' + callbackfun + '(' + result + ')')

    @run_on_executor
    def _get(self, request_id, api_url, *args, **kwargs):
        request = self._get_request_arguments(*args, **kwargs)
        logger.info(api_url)
        cache_result, cache_id = None, None
        if request:
            res = self._request_service(request_id, **request)
        else:
            res = self._request_service(request_id)
        if res is None:
            raise HTTPError(404, "Not found")
        else:
            result = {"result": res}
        return result, cache_id,request

    @abc.abstractmethod
    def _get_request_arguments(self, *args, **kwargs):
        raise NotImplementedError('call to abstract method %s._get_request_arguments' % self.__class__)

    @abc.abstractmethod
    def _request_service(self, request_id, **kwargs):
        raise NotImplementedError('call to abstract method %s._request_service' % self.__class__)
